package com.tenebrous.jestic.service.framwork.meber.author;

import com.tenebrous.jestic.entity.TreeSerializable;
import com.tenebrous.jestic.entity.framwork.meber.author.AuthMenu;
import com.tenebrous.jestic.mapper.idao.framwork.meber.author.AuthMenuMapper;
import com.tenebrous.jestic.service.SuperService;
import com.rain.ops.sdk.dto.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Service
public class AuthMenuService extends SuperService<AuthMenu> {

    @Autowired
    private AuthMenuMapper mapper;

    @Override
    @Autowired
    protected void setSuperMapper() {

        super.setSuperMapper(this.mapper);
    }

    public List<TreeSerializable> queryTree() {

        List<TreeSerializable> tlist = new ArrayList<>();
        List<AuthMenu> mlist = this.mapper.selectByCondition();
        tlist.addAll(mlist);

        return this.buildTree(tlist, "0");
    }

    public List<AuthMenu> queryRoleMenuTree(String[] roleids) {
        List<TreeSerializable> result = new ArrayList<>();
        List<AuthMenu> rmlist = this.mapper.selectByRoleids(roleids);
        for (AuthMenu mitem : rmlist) {
            result.add(mitem);
            this.findParent(mitem.getPid(), result);
        }
        List<AuthMenu> aml = new ArrayList<>();
        List<TreeSerializable> tlist = this.buildTree(result, "0");
        for (TreeSerializable ts : tlist) {
            aml.add((AuthMenu) ts);
        }
        aml.sort(Comparator.comparing(AuthMenu::getLeve).thenComparing(AuthMenu::getSort));
        return aml;
    }

    public List<AuthMenu> queryRoleRootMenuTree(String[] roleids) {
        List<TreeSerializable> result = new ArrayList<>();
        List<AuthMenu> rmlist = this.mapper.selectByRoleids(roleids);
        for (AuthMenu mitem : rmlist) {
            result.add(mitem);
            this.findParent(mitem.getPid(), result);
        }
        List<AuthMenu> aml = new ArrayList<>();
        for (TreeSerializable mitem : result) {
            if ("0".equals(mitem.getPid())) {
                aml.add((AuthMenu) mitem);
            }
        }
        aml.sort(Comparator.comparing(AuthMenu::getSort));
        return aml;
    }

    public List<AuthMenu> queryRoleChildMenuTree(String[] roleids, String parentmenuid) {
        List<AuthMenu> result = new ArrayList<>();
        List<AuthMenu> rmlist = this.mapper.selectByRoleids(roleids);
        for (AuthMenu mitem : rmlist) {
            if (mitem.getPid().equals(parentmenuid)) {
                result.add(mitem);
            }
        }
        return result;
    }

    public List<TreeSerializable> queryChildTree(String id) {
        List<TreeSerializable> tlist = new ArrayList<>();
        List<AuthMenu> mlist = this.mapper.selectByCondition();
        tlist.addAll(mlist);

        return this.buildTree(tlist, id);
    }

    /**
     * 向上移动
     *
     * @param id
     * @return
     */
    @Transactional
    public ApiResult up(String id) {
        AuthMenu item = this.mapper.selectByPrimaryKey(id);
        if (item != null) {
            AuthMenu cd = new AuthMenu();
            cd.setPid(item.getPid());
            List<AuthMenu> list = this.mapper.select(cd);
            list.sort(Comparator.comparing(AuthMenu::getSort).reversed());

            AuthMenu titem = list.stream().filter(o -> o.getSort() < item.getSort()).findFirst().orElse(null);
            if (titem != null) {
                item.setSort(item.getSort() + titem.getSort());
                titem.setSort(item.getSort() - titem.getSort());
                item.setSort(item.getSort() - titem.getSort());

                this.mapper.updateByPrimaryKeySelective(item);
                this.mapper.updateByPrimaryKeySelective(titem);
                return new ApiResult(200, "上移成功。");
            } else {
                return new ApiResult(999, "无法上移，已是最前一条记录。");
            }
        }
        return new ApiResult(999, "上移失败，指定导航不存在。");
    }

    /**
     * 向下移动
     *
     * @param id
     * @return
     */
    @Transactional
    public ApiResult down(String id) {
        AuthMenu item = this.mapper.selectByPrimaryKey(id);
        if (item != null) {
            AuthMenu cd = new AuthMenu();
            cd.setPid(item.getPid());
            List<AuthMenu> list = this.mapper.select(cd);
            list.sort(Comparator.comparing(AuthMenu::getSort));

            AuthMenu titem = list.stream().filter(o -> o.getSort() > item.getSort()).findFirst().orElse(null);
            if (titem != null) {
                item.setSort(item.getSort() + titem.getSort());
                titem.setSort(item.getSort() - titem.getSort());
                item.setSort(item.getSort() - titem.getSort());

                this.mapper.updateByPrimaryKeySelective(item);
                this.mapper.updateByPrimaryKeySelective(titem);
                return new ApiResult(200, "下移成功。");
            } else {
                return new ApiResult(999, "无法下移，已是最后一条记录。");
            }
        }
        return new ApiResult(999, "下移失败，指定导航不存在。");
    }

    public int updateEnabled(String id, int enabled) {
        AuthMenu item = this.mapper.selectByPrimaryKey(id);
        if (item != null) {
            item.setEnabled(enabled);
            return this.mapper.updateByPrimaryKeySelective(item);
        }
        return 0;
    }

    private void findParent(String pid, List<TreeSerializable> result) {
        if (!"0".equalsIgnoreCase(pid)) {
            TreeSerializable pitem = result.stream().filter(o -> o.getId().equals(pid)).findFirst().orElse(null);
            if (pitem == null) {
                pitem = this.mapper.selectByPrimaryKey(pid);
                if (pitem != null) {
                    result.add(pitem);
                    this.findParent(pitem.getPid(), result);
                }
            }
        }
    }
}
